/*
 * @Author: chenbolin@msn.cn
 * @Date: 2023-08-24 14:46:33
 * @LastEditors: chenbolin@msn.cn
 * @LastEditTime: 2023-10-26 16:38:21
 * @FilePath: \Remote\src\App\UserMain.c
 * @Description:
 *
 * Copyright (c) 2023 by ${git_name_email}, All Rights Reserved.
 */
#include "Sys.h"
#include "SysButton.h"
#include "Joystick.h"
#include "Wireless.h"
#include "MotionCtrl.h"
#include "Button.h"
#include "LED.h"

#define WIRELESS_PROTO_VERSION 0x01

#pragma pack(1)
typedef struct
{
    uint8_t emergencyStop : 1; // 急停
    uint8_t horn : 1;          // 喇叭
    uint8_t start : 1;         // 启动
    uint8_t stop : 1;          // 熄火
    uint8_t light : 1;         // 照明
    uint8_t reserve : 3;
} RemoterIO_t;

typedef struct
{
    int16_t current[SYS_VALVE_CH_COUNT]; // 电流
    RemoterIO_t io;                      // IO状态
    uint16_t frequency;                  // 比例阀频率
    uint16_t throttle;                   // 油门
} RemoterData_t;
#pragma pack()

static bool gSysAuthorized = true;
static bool gRemoteEnable = false;

static void wirelessDataHandle(WirelessCmd_t cmd, uint8_t version, unsigned char *data, unsigned short length)
{
    RemoterData_t rdata;
    uint16_t current;
    uint8_t i;

    if (version == WIRELESS_PROTO_VERSION)
    {
        if (WIRELESS_CMD_RECEIVER_DATA == cmd && 1 == length)
        {
            memset(&rdata, 0, sizeof(RemoterData_t));

            /*receiver data handle*/
            gSysAuthorized = (data[0] != 0);

            /*remote control state update*/
            if (gRemoteEnable && gSysAuthorized)
            {
                if (!SysIsEmergencyStop())
                {
                    for (i = 0; i < SYS_VALVE_CH_COUNT; i++)
                    {
                        current = MTRealCurrent((SysValveChannel_t)i, SYS_JOYSTICK_DIR_UP);
                        rdata.current[i] = current > 0 ? current : -MTRealCurrent((SysValveChannel_t)i, SYS_JOYSTICK_DIR_DOWN);
                    }
                }
                else
                {
                    gRemoteEnable = false; // 急停按下后清除使能
                    MotionCtrlReset();
                }
                rdata.io.start = ButtonGetState(BUTTON_ID_ENGINE_START);
                rdata.io.stop = ButtonGetState(BUTTON_ID_ENGINE_STOP);
                rdata.io.light = ButtonGetState(BUTTON_ID_LIGHTING);
                rdata.throttle = SysThrottleValue();
            }

            rdata.io.emergencyStop = SysIsEmergencyStop();
            rdata.io.horn = ButtonGetState(BUTTON_ID_HORN);
            rdata.frequency = SYS_VALVE_FREQUENCY;

            if (!gRemoteEnable)
            {
                gRemoteEnable = rdata.io.horn; // 按下喇叭使能遥控
            }

            WirelessSendData(WIRELESS_CMD_REMOTE_DATA, (uint8_t *)&rdata, sizeof(RemoterData_t));
        }
    }
}

/*LED 指示灯
 */
static void ledStateHandle(void)
{
    /*信号指示灯*/
    if (SysIsEmergencyStop()) // 急停
    {
        LEDStateSet(LED_ID_SIGNAL, LED_COLOR_RED, LED_STATE_BLINK_SLOW); // 红色慢闪
    }
    else
    {
        if (WirelessDisconnect()) // 未连接
        {
            LEDStateSet(LED_ID_SIGNAL, LED_COLOR_RED, LED_STATE_ON); // 红色常亮
        }
        else // 已连接
        {
            if (gSysAuthorized) // 接收器已授权
            {
                if (SysWirelessSignalLevel() < 1) // 信号弱
                {
                    LEDStateSet(LED_ID_SIGNAL, LED_COLOR_GREEN, LED_STATE_BLINK_SLOW); // 绿色慢闪
                }
                else
                {
                    LEDStateSet(LED_ID_SIGNAL, LED_COLOR_GREEN, LED_STATE_ON); // 绿色常亮
                }
            }
            else // 接收器未授权
            {
                LEDStateSet(LED_ID_SIGNAL, LED_COLOR_GREEN, LED_STATE_BLINK_FAST); // 绿色快闪
            }
        }
    }

    /*电源指示灯*/
    if (SysWorkMode() == SYS_WORK_MODE_CONFIG)
    {
        if (ButtonGetState(BUTTON_ID_ENGINE_START) || ButtonGetState(BUTTON_ID_ENGINE_STOP)) // 按下闪烁
        {
            LEDStateSet(LED_ID_POWER, LED_COLOR_GREEN, LED_STATE_BLINK_FAST); // 绿色快闪
        }
        else
        {
            LEDStateSet(LED_ID_POWER, LED_COLOR_GREEN, LED_STATE_ON); // 绿色常亮
        }
    }
    else
    {
        if (SysBatteryPercentage() <= 10) // 电量低
        {
            LEDStateSet(LED_ID_POWER, LED_COLOR_RED, LED_STATE_BLINK_SLOW); // 红色慢闪
        }
        else
        {
            LEDStateSet(LED_ID_POWER, LED_COLOR_RED, LED_STATE_ON); // 红色常亮
        }
    }
}

typedef struct
{
    SysValveChannel_t ch;
    SysJoystickDirect_t dir;
    uint16_t value;
} ValveCurrent_t;

/*获取当前有动作的摇杆的信息*/
static ValveCurrent_t *getCurrent(void)
{
    static ValveCurrent_t current;
    uint16_t value;
    uint8_t i;

    for (i = 0; i < SYS_VALVE_CH_COUNT; i++)
    {
        value = MTRealCurrent((SysValveChannel_t)i, SYS_JOYSTICK_DIR_UP);
        if (value > 0)
        {
            current.ch = (SysValveChannel_t)i;
            current.dir = SYS_JOYSTICK_DIR_UP;
            current.value = value;
            return &current;
        }

        value = MTRealCurrent((SysValveChannel_t)i, SYS_JOYSTICK_DIR_DOWN);
        if (value > 0)
        {
            current.ch = (SysValveChannel_t)i;
            current.dir = SYS_JOYSTICK_DIR_DOWN;
            current.value = value;
            return &current;
        }
    }

    return NULL;
}

static void buttonEventHandle(SysButtonEvent_t evt, uint8_t id, uint8_t io, uint8_t level)
{
    SysSettings_t *st = SysSettings();
    ValveCurrent_t *vc;

    if (SysWorkMode() == SYS_WORK_MODE_CONFIG && evt == SYS_BUTTON_EVENT_LEVEL_FLIP)
    {
        if (io == HAL_PIN_KEY_EMERGENCY_STOP)
        {
            if (level == 0) // 弹起保存参数
            {
                SysSettingsUpdate();
            }
        }
        else if (io == HAL_PIN_KEY_ENGINE_START)
        {
            if (level == 1) // press
            {
                vc = getCurrent();
                if (vc != NULL) // 记录电流最小值
                {
                    st->current[vc->ch][vc->dir].min = vc->value;
                }
            }
        }
        else
        {
            if (level == 1) // press
            {
                vc = getCurrent();
                if (vc != NULL) // 记录电流最大值
                {
                    if(SysSpeedMode() == SYS_SPEED_MODE_FAST)
                    {
                        st->current[vc->ch][vc->dir].fastMax = vc->value; //快速最大
                    }
                    else
                    {
                        st->current[vc->ch][vc->dir].slowMax = vc->value; //慢速最大
                    }
                }
            }
        }
    }
}

static void btnEventRegist(void)
{
    uint8_t i = 0;
    SysButtonRegister(i++, HAL_PIN_KEY_EMERGENCY_STOP, buttonEventHandle);
    SysButtonRegister(i++, HAL_PIN_KEY_ENGINE_START, buttonEventHandle);
    SysButtonRegister(i++, HAL_PIN_KEY_ENGINE_STOP, buttonEventHandle);
}

void UserMainInitialize(void)
{
    MotionCtrlInitialize();
    JoystickInitialize();
    WirelessInitialize(wirelessDataHandle);
    LEDInitialize();
    btnEventRegist();
}

void UserMainPoll(void)
{
    JoystickPoll();
    WirelessPoll();
    ledStateHandle();
    LEDPoll();
}
